﻿using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;

public class AesUtil
{
    private const string PREFIX_AES = "A-";
    private const string AES_ALGORITHM = "AES/CBC/PKCS5PADDING";
    private const int AES_KEY_LENGTH = 32;

    public static byte[] Encrypt(string algorithm, byte[] key, byte[] iv, byte[] bytes)
    {
        using (var aes = new AesCryptoServiceProvider())
        {
            aes.Key = key;
            aes.IV = iv;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;

            using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
            {
                return encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
            }
        }
    }

    public static byte[] Decrypt(string algorithm, byte[] key, byte[] iv, byte[] bytes)
    {
        using (var aes = new AesCryptoServiceProvider())
        {
            aes.Key = key;
            aes.IV = iv;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;

            using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
            {
                return decryptor.TransformFinalBlock(bytes, 0, bytes.Length);
            }
        }
    }

    public static string EncryptHex(string algorithm, byte[] key, byte[] iv, string data, Encoding encoding)
    {
        return BitConverter.ToString(Encrypt(algorithm, key, iv, encoding.GetBytes(data))).Replace("-", "");
    }

    public static string DecryptHex(string algorithm, byte[] key, byte[] iv, string encrypted, Encoding encoding)
    {
        var bytes = Convert.FromBase64String(encrypted);
        var decrypted = Decrypt(algorithm, key, iv, bytes);
        return encoding.GetString(decrypted);
    }

    public static string Encode(string data, string password)
    {
        password = FillPassword(password);
        return PREFIX_AES + EncryptHex(AES_ALGORITHM, Encoding.UTF8.GetBytes(password), Encoding.UTF8.GetBytes(password.Substring(0, 16)), data, Encoding.UTF8);
    }

    public static string Decode(string data, string password)
    {
        password = FillPassword(password);
        return DecryptHex(AES_ALGORITHM, Encoding.UTF8.GetBytes(password), Encoding.UTF8.GetBytes(password.Substring(0, 16)), data, Encoding.UTF8);
    }

    private static string FillPassword(string password)
    {
        if (string.IsNullOrEmpty(password))
        {
            throw new ArgumentException("Invalid encryption key");
        }

        if (password.Length > AES_KEY_LENGTH)
        {
            return password.Substring(0, AES_KEY_LENGTH);
        }
        else
        {
            return password;
        }
    }

    public static bool IsHex(string input)
    {
        var regex = new Regex(@"^[a-fA-F0-9]+$");
        return regex.IsMatch(input);
    }
}